package com.snake.springboot.authority.service.impl;

import com.snake.springboot.authority.api.model.AuthBuyStrategyModel;
import com.snake.springboot.authority.api.model.AuthOperatorStrategyModel;
import com.snake.springboot.authority.api.model.StrategyExpireModel;
import com.snake.springboot.authority.api.request.AuthOperatorStrategyQuery;
import com.snake.springboot.authority.api.request.AuthorizationDefaultSave;
import com.snake.springboot.authority.api.response.AuthOperatorStrategyRsp;
import com.snake.springboot.authority.api.response.OperatorStrategySumRsp;
import com.snake.springboot.authority.api.service.AuthorizationStrategyService;
import com.snake.springboot.authority.dao.mybatis.entity.AuthOperatorStrategyDO;
import com.snake.springboot.authority.dao.mybatis.entity.AuthOperatorStrategyExtDO;
import com.snake.springboot.authority.dao.mybatis.entity.AuthStrategyDO;
import com.snake.springboot.authority.dao.mybatis.entity.OperatorStrategySumDO;
import com.snake.springboot.authority.dao.mybatis.mappers.AuthOperatorStrategyMapper;
import com.snake.springboot.authority.dao.mybatis.mappers.AuthStrategyMapper;
import com.snake.springboot.authority.service.assembler.AuthStrategyOperatorAssembler;
import org.snake.common.utils.CollectionUtils;
import org.snake.common.utils.ListUtils;
import org.snake.common.utils.PropertyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 类 {@code AuthorizationStrategyServiceImpl}  <br> .
 * <p>权限策略授权实现类
 * <p>创建时间：2025/02/08
 *
 * @author Huang.yj
 */
@Service
public class AuthorizationStrategyServiceImpl implements AuthorizationStrategyService {

    private AuthOperatorStrategyMapper authOperatorStrategyMapper;
    private AuthStrategyMapper authStrategyMapper;

    @Autowired
    public AuthorizationStrategyServiceImpl(AuthOperatorStrategyMapper authOperatorStrategyMapper,
                                            AuthStrategyMapper authStrategyMapper){
        this.authOperatorStrategyMapper = authOperatorStrategyMapper;
        this.authStrategyMapper = authStrategyMapper;
    }

    @Override
    public int authorization(List<AuthOperatorStrategyModel> models) {
        List<AuthOperatorStrategyDO> authDOS = AuthStrategyOperatorAssembler.authDOAss(models);
        AuthOperatorStrategyDO keyDO = new AuthOperatorStrategyDO(authDOS.get(0).getOperatorId(),null);
        authOperatorStrategyMapper.delete(keyDO);
        return authOperatorStrategyMapper.insertBatch(authDOS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int someAuthor(List<AuthOperatorStrategyModel> models) {
        if (models == null || models.isEmpty()){
            return 0;
        }
        List<AuthOperatorStrategyDO> authDOS = AuthStrategyOperatorAssembler.authDOAss(models);
        authOperatorStrategyMapper.deleteList(authDOS);
        return authOperatorStrategyMapper.insertBatch(authDOS);
    }

    @Override
    public int cancelSomeAuthor(List<AuthOperatorStrategyModel> models) {
        if (models == null || models.isEmpty()){
            return 0;
        }
        List<AuthOperatorStrategyDO> authDOS = ListUtils.copy(models, AuthOperatorStrategyDO.class);
        return authOperatorStrategyMapper.cancelSomeAuthor(authDOS);
    }

    @Override
    public int authorizationDefault(AuthorizationDefaultSave model) {
        List<AuthStrategyDO> authDefaultStrategyDOS = authStrategyMapper.findDefaultBySystem(model.getSystemIds());
        if(CollectionUtils.isNullOrEmpty(authDefaultStrategyDOS)) return 0;
        List<AuthOperatorStrategyDO> authDOS =
                createAuthOperatorStrategyDOList(model.getOperatorId(), authDefaultStrategyDOS);
        return authOperatorStrategyMapper.insertBatch(authDOS);
    }

    @Override
    public int cancelAuthorization(String operatorId) {
        AuthOperatorStrategyDO keyDO = new AuthOperatorStrategyDO(operatorId,null);
        return authOperatorStrategyMapper.delete(keyDO);
    }

    @Override
    public List<AuthOperatorStrategyRsp> queryOperatorStrategy(AuthOperatorStrategyQuery query) {
        AuthOperatorStrategyExtDO queryDO = new AuthOperatorStrategyExtDO();
        PropertyUtils.copyProperties(queryDO, query);
        List<AuthOperatorStrategyExtDO> extDOS = authOperatorStrategyMapper.findStrategy(queryDO);
        List<AuthOperatorStrategyRsp> result = ListUtils.copy(extDOS,AuthOperatorStrategyRsp.class);
        return result;
    }

    private List<AuthOperatorStrategyDO> createAuthOperatorStrategyDOList(String operatorId, List<AuthStrategyDO> authDefaultStrategyDOS){
        List<AuthOperatorStrategyDO> doList = new ArrayList<>();
        AuthOperatorStrategyDO authOperatorStrategyDO;
        for(AuthStrategyDO defaultDO : authDefaultStrategyDOS){
            authOperatorStrategyDO = new AuthOperatorStrategyDO(operatorId, defaultDO.getStrategyId());
            authOperatorStrategyDO.setExpireState(StrategyExpireModel.EVERLASTING);
            doList.add(authOperatorStrategyDO);
        }
        return doList;
    }

    @Override
    public List<OperatorStrategySumRsp> strategySum(List<String> operatorIds) {
        List<OperatorStrategySumDO> dos = authOperatorStrategyMapper.findStrategySum(operatorIds);
        return ListUtils.copy(dos,OperatorStrategySumRsp.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void buyAuthor(List<AuthBuyStrategyModel> models) {
        List<AuthOperatorStrategyDO> queryDO = ListUtils.copy(models, AuthOperatorStrategyDO.class);
        List<AuthOperatorStrategyDO> dos = authOperatorStrategyMapper.queryBuyList(queryDO);
        List<AuthOperatorStrategyDO> strategyDOS = AuthStrategyOperatorAssembler.authBuyDOAss(models,dos);
        if (ListUtils.isEmpty(strategyDOS)){
            return;
        }
        authOperatorStrategyMapper.cancelSomeAuthor(strategyDOS);
        authOperatorStrategyMapper.insertBatch(strategyDOS);
    }

    @Override
    public void cancelBuyAuthor(List<AuthBuyStrategyModel> models) {
        List<AuthOperatorStrategyDO> queryDO = ListUtils.copy(models, AuthOperatorStrategyDO.class);
        List<AuthOperatorStrategyDO> dos = authOperatorStrategyMapper.queryBuyList(queryDO);
        List<AuthOperatorStrategyDO> strategyDOS = AuthStrategyOperatorAssembler.authRetDOAss(models,dos);
        if (!ListUtils.isEmpty(dos)){
            authOperatorStrategyMapper.cancelSomeAuthor(dos);
        }
        if (!ListUtils.isEmpty(strategyDOS)){
            authOperatorStrategyMapper.insertBatch(strategyDOS);
        }
    }
}
